home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / TEX-UTIL / TR2LATEX / c / tr < prev    next >
Text File  |  1992-04-27  |  27KB  |  1,055 lines

  1. /*
  2. ** tr2latex - troff to LaTeX converter
  3. ** $Id: tr.c,v 2.2 1992/04/27 15:13:26 Christian_Engel Dist krischan $
  4. ** COPYRIGHT (C) 1987 Kamal Al-Yahya, 1991,1992 Christian Engel
  5. ** 
  6. ** Module: tr.c
  7. **
  8. ** This module contains the HARD-WIRED rules of the translator.
  9. ** It should be handled with care.
  10. */
  11.  
  12. #include    "setups.h"
  13. #include    "protos.h"
  14.  
  15. int def_count = 0;
  16. int mydef_count = 0;
  17.  
  18. extern bool man;        /* man flag */
  19.  
  20. void troff_tex (char *pin, char *pout, int mid, int rec)
  21. {
  22.     char eqn_no[MAXWORD], w[MAXWORD], ww[MAXLINE], tmp[MAXWORD], tmp2[MAXWORD];
  23.     char *p, **pw;
  24.     int len,c,c1,c2,i,j;
  25.     int ref = 0;
  26.     int put_brace = 0;
  27.     int first_word = 1;
  28.     int no_word = 1;
  29.     int arg = 0;
  30.     int par = 0;
  31.     int illegal = 0;
  32.     int floating = 0;
  33.     static int delim_defd = 0;    /* whether math delimiter has been defined */
  34.     static char DELIM [] = "$";
  35.     float flen;
  36.     int N;
  37.     int RSRE = 0;            /* block indentation */
  38.     int EXEE = 0;            /* example indentation */
  39.     int NTNE = 0;            /* note indentation */
  40.     int thisfont = 1;        /* default font is roman */
  41.     int lastfont = 1;        /* default last font is roman */
  42.     int offset = 0;            /* amount to offset pin */
  43.     
  44.     *pout = EOS;
  45.     w[0] = EOS;
  46.     ww[0] = EOS;
  47.     tmp[0] = EOS;
  48.     tmp2[0] = EOS;
  49.     while (*pin != EOS) {
  50.         len = getword(pin,w);
  51.         c1 = (first_word? '\n': pin[-1]);
  52.         c2 = pin[0];
  53.         pin += len;
  54.         if (!isspace(w[0]))
  55.             no_word = 0;
  56.         /* first check if we are in math mode */
  57.         if (math_mode) {
  58.             len = get_till_space(pin,ww);
  59.             sprintf(tmp,"%s%s",w,ww);
  60.             if (strcmp(w,"delim") == 0) {
  61.                 delim_defd = 1;
  62.                 pin += skip_white(pin);
  63.                 DELIM[0] = *pin;
  64.                 pin = skip_line(pin);
  65.             }
  66.             /* check if it is a math delimiter; switch to non-math mode if so*/
  67.             else if (delim_defd && strcmp(w,DELIM) == 0) {
  68.                 math_mode = 0;
  69.                 *pout++ = '$';
  70.             }
  71.             /* check for illegal macros here */
  72.             else if (len > 0 && def_count > 0 && (i=is_def(tmp)) >= 0) {
  73.                 pin += len;
  74.                 pout = strapp(pout,def[i].replace);
  75.             }
  76.             /* See if it is a (legally) defined macro */
  77.             else if (def_count > 0 && (i=is_def(w)) >= 0) {
  78.                 if (def[i].illegal)
  79.                     pout = strapp(pout,def[i].replace);
  80.                 else {
  81.                     pout = strapp(pout,"\\");
  82.                     pout = strapp(pout,w);
  83.                 }
  84.             }
  85.             /* Search for commands in some order;
  86.                start with non-alphanumeric symbols */
  87.             else if (strcmp(w,"#") == 0 || strcmp(w,"&") == 0
  88.                      || strcmp(w,"%") == 0 || strcmp(w,"_") == 0) {
  89.                 pout = strapp(pout,"\\");
  90.                 pout = strapp(pout,w);
  91.             }
  92.             else if (strcmp(w,"=") == 0) {
  93.                 if (*pin == '=') {
  94.                     pin++;
  95.                     pout = strapp(pout,"\\equiv");
  96.                 }
  97.                 else
  98.                     pout = strapp(pout,"=");
  99.             }
  100.             else if (strcmp(w,"<") == 0 || strcmp(w,">") == 0) {
  101.                 if (*pin == '=') {
  102.                     pin++;
  103.                     if (strcmp(w,"<") == 0)
  104.                         pout = strapp(pout,"\\le");
  105.                     else
  106.                         pout = strapp(pout,"\\ge");
  107.                 }
  108.             }
  109.             else if (strcmp(w,"-") == 0) {
  110.                 if (*pin == '>') {
  111.                     pin++;
  112.                     pout = strapp(pout,"\\to");
  113.                 }
  114.                 else if (*pin == '+') {
  115.                     pin++;
  116.                     pout = strapp(pout,"\\mp");
  117.                 }
  118.                 else
  119.                     *pout++ = '-';
  120.             }
  121.             else if (strcmp(w,"+") == 0) {
  122.                 if (*pin == '-') {
  123.                     pin++;
  124.                     pout = strapp(pout,"\\pm");
  125.                 }
  126.                 else
  127.                     *pout++ = '+';
  128.             }
  129.             else if (strcmp(w,"\"") == 0) {
  130.                 len = get_no_math(pin,ww);
  131.                 pin += len+1;
  132.                 if (len > 1) {
  133.                     sprintf(tmp,"\\ \\it\\hbox{%s}",ww);
  134.                     pout = strapp(pout,tmp);
  135.                 }
  136.                 else if (len == 1)
  137.                     *pout++ = ww[0];
  138.             }
  139.             /* Now search for symbols that start with a captial */
  140.             else if (strcmp(w,".EN") == 0) {
  141.                 math_mode = 0;
  142.                 if ((len=strlen(eqn_no)) > 0)
  143.                 {
  144.                     sprintf(tmp,"\\eqno %s",eqn_no);
  145.                     pout = strapp(pout,tmp);
  146.                 }
  147.                 eqn_no[0] = EOS;
  148.                 c1 = *--pout;
  149.                 c2 = *--pout;
  150.                 if (c1 == '\n' && c2 == '$')
  151.                     *--pout = EOS;
  152.                 else {
  153.                     pout += 2;
  154.                     pout = strapp(pout,"$$");
  155.                 }
  156.             }
  157.             /* Now search for symbols that start with a small letter */
  158.             else if (strcmp(w,"bold") == 0 || strcmp(w,"roman") == 0 ||
  159.                      strcmp(w,"italic") == 0) {
  160.                 pin += get_arg(pin,ww,1);
  161.                 if (strcmp(w,"bold") == 0) {
  162.                     sprintf(tmp,"{\\bf %s}",ww);
  163.                     pout = strapp(pout,tmp);
  164.                 }
  165.                 else if (strcmp(w,"roman") == 0) {
  166.                     sprintf(tmp,"{\\rm %s}",ww);
  167.                     pout = strapp(pout,tmp);
  168.                 }
  169.                 else {
  170.                     sprintf(tmp,"{\\it %s}",ww);
  171.                     pout = strapp(pout,tmp);
  172.                 }
  173.             }
  174.             else if (strcmp(w,"define") == 0) {
  175.                 if (def_count >= MAXDEF) {
  176.                     fprintf(stderr, "Too many defines. MAXDEF=%d\n",MAXDEF);
  177.                     exit(-1);
  178.                 }
  179.                 for (i=0; *--pout != '$' && (unsigned)i < MAXLEN; i++)
  180.                     tmp[i] = *pout;
  181.                 tmp[i] = EOS;
  182.                 strcat(tmp,"$$");
  183.                 *--pout = EOS;
  184.                 pin += skip_white(pin);
  185.                 pin += get_defword(pin,w,&illegal);
  186.                 pin += skip_white(pin);
  187.                 pin += getdef(pin,ww);
  188.                 if (illegal) {
  189.                     def[def_count].illegal = 1;
  190.                     fprintf(stderr, "illegal TeX macro, %s, replacing it\n",w);
  191.                     p = (char *)malloc((unsigned)(strlen(ww)+1)*sizeof(char));
  192.                     strcpy(p,ww);
  193.                     def[def_count].replace = p;
  194.                 }
  195.                 else {
  196.                     def[def_count].illegal = 0;
  197.                     sprintf(tmp2,"\\def\\%s{%s}\n",w,ww);
  198.                     pout = strapp(pout,tmp2);
  199.                 }
  200.                 p = (char *)malloc((unsigned)(strlen(w)+1)*sizeof(char));
  201.                 strcpy(p,w);
  202.                 def[def_count++].def_macro = p;
  203.                 pin += skip_white(pin);
  204.                 for (j=i+1; j >= 0; j--)
  205.                     *pout++ = tmp[j];
  206.                 tmp[0] = EOS;
  207.             }
  208.             else if (strcmp(w,"gsize") == 0 || strcmp(w,"gfont") == 0)
  209.                 pin = skip_line(pin);
  210.             else if (strcmp(w,"left") == 0 || strcmp(w,"right") == 0) {
  211.                 sprintf(tmp,"\\%s",w);
  212.                 pout = strapp(pout,tmp);
  213.                 pin += skip_white(pin);
  214.                 len = getword(pin,ww);
  215.                 if (strcmp(ww,"floor") == 0) {
  216.                     pin += len;
  217.                     if (strcmp(w,"left") == 0)
  218.                         pout = strapp(pout,"\\lfloor");
  219.                     else
  220.                         pout = strapp(pout,"\\rfloor");
  221.                 }
  222.                 else if (strcmp(ww,"nothing") == 0 || ww[0] == '\"') {
  223.                     pin += len;
  224.                     *pout++ = '.';
  225.                     if (ww[0] == '\"')    pin++;
  226.                 }
  227.                 else if (*pin == '{' || *pin == '}')
  228.                     *pout++ = '\\';
  229.             }
  230.             else if (strcmp(w,"over") == 0) {
  231.                 if (!first_word) {
  232.                     pout--;
  233.                     for (i=0; isspace (*pout); i++)
  234.                         tmp[i] = *pout--;
  235.                     if (*pout == '}' && put_brace == 0)
  236.                         *pout = ' ';
  237.                     else {
  238.                         for (; !isspace(*pout) && *pout != '$'; i++)
  239.                             tmp[i] = *pout--;
  240.                         put_brace = 0;
  241.                         *++pout = '{';
  242.                     }
  243.                     for (j=i-1; j >= 0; j--)
  244.                         *++pout = tmp[j];
  245.                     *++pout = EOS;
  246.                 }
  247.                 pout = strapp(pout,"\\over");
  248.                 pin += skip_white(pin);
  249.                 *pout++ = ' ';
  250.                 if (*pin == '{')
  251.                     pin++;
  252.                 else {
  253.                     pin = get_over_arg(pin,ww);
  254.                     pout = strapp(pout,ww);
  255.                     if (*pin != EOS || !first_word)
  256.                         *pout++ = '}';
  257.                 }
  258.             }
  259.             else if (strcmp(w,"size") == 0)
  260.                 pin += get_arg(pin,ww,0);
  261.             else if (strcmp(w,"sup") == 0 || strcmp(w,"to") == 0 ||
  262.                      strcmp(w,"sub") == 0 || strcmp(w,"from") == 0) {
  263.                 while ((c = *--pout) == ' ' || c == '\t' || c == '\n')
  264.                     /* EMPTY */
  265.                     ;
  266.                 *++pout = EOS;
  267.                 if (strcmp(w,"sup") == 0 || strcmp(w,"to") == 0)
  268.                     pout = strapp(pout,"^");
  269.                 else
  270.                     pout = strapp(pout,"_");
  271.                 pin += skip_white(pin);
  272.                 len = get_sub_arg(pin,ww);
  273.                 pin += len;
  274.                 if (len > 1) {
  275.                     sprintf(tmp,"{%s}",ww);
  276.                     pout = strapp(pout,tmp);
  277.                     len = skip_white(pin);
  278.                     pin += len;
  279.                     (void) getword(pin,ww);
  280.                     if (strcmp(ww,"over") == 0)
  281.                         put_brace = 1;
  282.                     pin -= len;
  283.                 }
  284.                 else
  285.                     pout = strapp(pout,ww);
  286.             }
  287.             else if (strcmp(w,"up") == 0 || strcmp(w,"down") == 0
  288.                      || strcmp(w,"fwd") == 0 || strcmp(w,"back") == 0) {
  289.                 if (strcmp(w,"up") == 0) {
  290.                     pout = strapp(pout,"\\raise");
  291.                     strcpy(tmp,"ex");
  292.                 }
  293.                 else if (strcmp(w,"down") == 0) {
  294.                     pout = strapp(pout,"\\lower");
  295.                     strcpy(tmp,"ex");
  296.                 }
  297.                 else if (strcmp(w,"fwd") == 0) {
  298.                     pout = strapp(pout,"\\kern");
  299.                     strcpy(tmp,"em");
  300.                 }
  301.                 else if (strcmp(w,"back") == 0) {
  302.                     pout = strapp(pout,"\\kern-");
  303.                     strcpy(tmp,"em");
  304.                 }
  305.                 pin += skip_white(pin);
  306.                 pin += getword(pin,ww);
  307.                 len = atoi(ww);        flen = len/100.;
  308.                 ww[0] = EOS;
  309.                 sprintf(tmp2,"%4.2f%s",flen,tmp);
  310.                 pout = strapp(pout,tmp2);
  311.             }
  312.             /* Now check if the word is a member of a group */
  313.             else if (CAP_GREEK(w) > 0) {
  314.                 GR_to_Greek(w,ww);
  315.                 pout = strapp(pout,ww);
  316.             }
  317.             else if (is_flip(w) >= 0) {
  318.                 if (!first_word) {
  319.                     len = skip_white(pin);
  320.                     pin += len;
  321.                     (void) getword(pin,ww);
  322.                     if (is_flip(ww) >= 0) {
  323.                         pin += strlen(ww);
  324.                         pout = flip_twice(pout,w,ww);
  325.                     }
  326.                     else {
  327.                         pin -= len;
  328.                         pout = flip(pout,w);
  329.                     }
  330.                 }
  331.                 else {
  332.                     pout = strapp(pout,"\\");
  333.                     pout = strapp(pout,w);
  334.                 }
  335.             }
  336.             else if (is_mathcom (w, ww) >= 0)
  337.                 pout = strapp (pout, ww);
  338.             else if (similar(w) > 0) {
  339.                 pout = strapp (pout, "\\");
  340.                 pout = strapp (pout, w);
  341.             }
  342.             
  343.             /* if none of the above math commands matched, it is an ordinary
  344.                symbol; just copy it */
  345.             
  346.             else
  347.                 pout = strapp(pout,w);
  348.         }
  349.         
  350.         /* check if it is a math delimiter; switch to math mode if so */
  351.         
  352.         else if (strcmp(w,"$") == 0 && de_arg > 0) {
  353.             de_arg++;
  354.             *pout++ = '#';
  355.         }
  356.         else if (delim_defd && strcmp(w,DELIM) == 0) {
  357.             math_mode = 1;
  358.             *pout++ = '$';
  359.         }
  360.         else if (strcmp(w,"$") == 0)
  361.             pout = strapp(pout,"\\$");
  362.         
  363.         /* check if it is a non-math troff command */
  364.         
  365.         else if (c2=='.' && !mid && (c1=='\n' || c1==EOS || first_word)) {
  366.             /* Search in some order; start with non-alphanumeric characters */
  367.             if (strcmp(w,".") == 0) {
  368.                 c1 = *pin;
  369.                 c2 = *++pin;
  370.                 if (c1 == '\\' && c2 == '\"') {
  371.                     ++pin;
  372.                     pin += get_line(pin,ww,0);
  373.                     pout = strapp(pout,"%");
  374.                     pout = strapp(pout,ww);
  375.                 }
  376.                 else {
  377.                     fprintf(stderr,
  378.                             "I cannot translate troff macro .%c%c\n",c1,c2);
  379.                     pin += get_line(pin,ww,0);
  380.                     sprintf(tmp,"%%.%c%c",c1,c2);
  381.                     pout = strapp(pout,tmp);
  382.                     pout = strapp(pout,ww);
  383.                     if (*pin == EOS)    *pout++ = '\n';
  384.                 }
  385.             }
  386.             /* Now search for commads that start with a capital */
  387.             else if (strcmp(w,".AB") == 0) {
  388.                 pin += get_arg(pin,ww,0);
  389.                 if (strcmp(ww,"no") == 0)
  390.                     pout = strapp(pout,"\\bigskip");
  391.                 else
  392.                     pout = strapp(pout,"\\begin{abstract}");
  393.             }
  394.             else if (strcmp(w,".B") == 0 || strcmp(w,".bf") == 0 ||
  395.                      strcmp(w,".I") == 0 || strcmp(w,".it") == 0 ||
  396.                      strcmp(w,".R") == 0 || strcmp(w,".rm") == 0 ||
  397.                      strcmp(w,".P") == 0) {
  398.                 if (strcmp(w,".R") == 0 || strcmp(w,".rm") == 0)
  399.                     strcpy(w,"rm");
  400.                 else if (strcmp(w,".B") == 0 || strcmp(w,".bf") == 0)
  401.                     strcpy(w,"bf");
  402.                 else if (strcmp(w,".I") == 0 || strcmp(w,".it") == 0)
  403.                     strcpy(w,"it");
  404.                 else {
  405.                     switch(lastfont) {
  406.                     case 1:
  407.                         strcpy (w, "rm");
  408.                         thisfont = 1;
  409.                         break;
  410.                     case 2:
  411.                         strcpy (w, "it");
  412.                         thisfont = 2;
  413.                         break;
  414.                     case 3:
  415.                         strcpy (w, "bf");
  416.                         thisfont = 3;
  417.                         break;
  418.                     default:
  419.                         strcpy (w, "rm");
  420.                         thisfont = 1;
  421.                         break;
  422.                     }
  423.                 }
  424.                 pin += get_arg(pin,ww,1);
  425.                 if (ww[0] == EOS) {
  426.                     pout = strapp(pout,"\\");
  427.                     pout = strapp(pout,w);
  428.                 }
  429.                 else {
  430.                     sprintf(tmp,"{\\%s %s",w,ww);
  431.                     pout = strapp(pout,tmp);
  432.                     while (1) {
  433.                         pin += get_arg(pin,ww,1);
  434.                         if (ww[0] == EOS)
  435.                             break;
  436.                         sprintf(tmp," %s",ww);
  437.                         pout = strapp(pout,tmp);
  438.                     }
  439.                     pout = strapp(pout,"}");
  440.                 }
  441.             }
  442.             else if (man && (strcmp(w,".BR") == 0 || strcmp(w,".BI") == 0
  443.                              || strcmp(w,".IR") == 0 || strcmp(w,".IB") == 0
  444.                              || strcmp(w,".RI") == 0 || strcmp(w,".RB") == 0)){
  445.                 pout = alternate(pin,pout,w);
  446.                 pin = skip_line(pin);
  447.                 *pout++ = '\n';
  448.             }
  449.             else if (strcmp(w,".BX") == 0) {
  450.                 pin += get_arg(pin,ww,1);
  451.                 sprintf(tmp,"\\fbox{%s}",ww);
  452.                 pout = strapp(pout,tmp);
  453.             }
  454.             else if (strcmp(w,".EQ") == 0) {
  455.                 math_mode = 1;
  456.                 put_brace = 0;
  457.                 pout = strapp(pout,"$$");
  458.                 len = get_arg(pin,eqn_no,0);
  459.                 if (strcmp(eqn_no,"I") == 0 || strcmp(eqn_no,"L") == 0) {
  460.                     fprintf(stderr,"lineups are ignored\n");
  461.                     pin += len;
  462.                     len = get_arg(pin,eqn_no,0);
  463.                 }
  464.                 if ((strlen(eqn_no)) > 0)
  465.                     pin += len;
  466.                 len = get_arg(pin,tmp,0);
  467.                 if (strcmp(tmp,"I") == 0 || strcmp(tmp,"L") == 0) {
  468.                     fprintf(stderr,"lineups are ignored\n");
  469.                     pin += len;
  470.                 }
  471.             }
  472.             else if (strcmp (w,".IP") == 0) {
  473.                 pin += get_arg (pin, ww, 1);
  474.                 pin = skip_line (pin);
  475.                 if (IP_stat == 0)
  476.                     pout = strapp(pout,"\\begin{IPlist}\n");
  477.                 sprintf(tmp,"\\IPitem{{%s}}\n",ww);
  478.                 pout = strapp(pout,tmp);
  479.                 if (de_arg > 0)        mydef[mydef_count].par = 2;
  480.                 else            IP_stat = 1;
  481.             }
  482.             else if (strcmp(w,".KE") == 0) {
  483.                 if (floating)
  484.                     pout = strapp(pout,"\\end{figure}");
  485.                 else
  486.                     pout = strapp(pout,"}");
  487.                 floating = 0;
  488.             }
  489.             else if (strcmp(w,".KF") == 0) {
  490.                 floating = 1;
  491.                 pout = strapp(pout,"\\begin{figure}");
  492.             }
  493.             else if (strcmp(w,".QP") == 0) {
  494.                 if (de_arg > 0)
  495.                     mydef[mydef_count].par = 4;
  496.                 else
  497.                     QP_stat = 1;
  498.                 pout = strapp(pout,"\\begin{quotation}");
  499.             }
  500.             else if (strcmp(w,".RE") == 0) {
  501.                 if (RSRE == 0)
  502.                     fprintf(stderr,".RE with no matching .RS\n");
  503.                 else {
  504.                     sprintf(tmp,"\\ind{%d\\parindent}", RSRE--);
  505.                     pout = strapp(pout,tmp);
  506.                 }
  507.             }
  508.             else if (strcmp(w,".RS") == 0) {
  509.                 pin += get_arg (pin, ww, 1);
  510.                 pin = skip_line (pin);
  511.                 sprintf(tmp,"\\ind{%d\\parindent}", ++RSRE);
  512.                 pout = strapp(pout,tmp);
  513.             }
  514.             else if (strcmp(w,".Re") == 0) {
  515.                 if (ref == 0)
  516.                     pout = strapp(pout,"\\REF\n");
  517.                 ref++;
  518.                 pin = skip_line(pin);
  519.                 pin += get_ref(pin,ww);
  520.                 sprintf(tmp,"\\reference{%s}",ww);
  521.                 pout = strapp(pout,tmp);
  522.             }
  523.             else if (man && (strcmp(w,".TP") == 0 || strcmp(w,".HP") == 0)) {
  524.                 if (IP_stat && TP_stat) {
  525.                     pout = strapp(pout,"\\end{IPlist}%\n");
  526.                     IP_stat = 0;
  527.                 }
  528.                 if (QP_stat && TP_stat) {
  529.                     pout = strapp(pout,"\\end{quotation}%\n");
  530.                     QP_stat = 0;
  531.                 }
  532.                 pin = skip_line(pin);
  533.                 pin += get_line(pin,ww,1);
  534.                 if (TP_stat == 0) {
  535.                     sprintf(tmp,"\\begin{TPlist}{%s}\n",ww);
  536.                     pout = strapp(pout,tmp);
  537.                 }
  538.                 sprintf(tmp,"\\item[{%s}]",ww);
  539.                 pout = strapp(pout,tmp);
  540.                 if (de_arg > 0)
  541.                     mydef[mydef_count].par = 3;
  542.                 else
  543.                     TP_stat = 1;
  544.             }
  545.             else if (man && (strcmp(w,".TH") == 0)) {
  546.                 /* expect something like .TH LS 1 "September 4, 1985"*/
  547.                 pin += get_allargs (pin, &pw, 1);
  548.                 if (pw [0] == NULL || pw [1] == NULL)
  549.                     fprintf (stderr, "Missing argument in troff macro .TH\n");
  550.                 else {
  551.                     for (j = 2; j <= 5; j++)
  552.                         if (pw [j] == NULL)
  553.                             break;
  554.                     for (; j <= 5; j++)
  555.                         pw[j] = "";
  556.                     sprintf (tmp, "\\phead{%s}{%s}{%s}{%s}{%s}",
  557.                              pw[0], pw[1], pw[2], pw[3], pw[4]);
  558.                     pout = strapp (pout, tmp);
  559.                 }
  560.             }
  561.             else if (man && strcmp (w, ".PN") == 0) {
  562.                 pin += get_allargs (pin, &pw, 1);
  563.                 if (pw [0] == NULL)
  564.                     fprintf (stderr, "Missing argument in troff macro .PN\n");
  565.                 else {
  566.                     sprintf (tmp, "{\\tt{}%s}%s ",
  567.                              pw [0], pw [1]? pw [1]: "");
  568.                     pout = strapp (pout, tmp);
  569.                 }
  570.             }
  571.             else if (man && strcmp (w, ".CW") == 0)
  572.                 pout = strapp (pout, "\\tt{}");
  573.             else if (man && strcmp (w, ".MS") == 0) {
  574.                 pin += get_allargs (pin, &pw, 1);
  575.                 if (pw [0] == NULL || pw [1] == NULL)
  576.                     fprintf (stderr, "Missing arguments in troff macro .MS\n");
  577.                 else {
  578.                     sprintf (tmp, "{\\tt{}%s}(%s)%s ",
  579.                              pw [0], pw [1], pw [2]? pw [2]: "");
  580.                     pout = strapp (pout, tmp);
  581.                 }
  582.             }
  583.             else if (man && strcmp (w, ".EX") == 0) {
  584.                 pin += get_arg (pin, ww, 1);
  585.                 pin = skip_line (pin);
  586.                 sprintf(tmp, "\\nofill\\ind{%d\\parindent}\\tt{}", ++EXEE);
  587.                 pout = strapp(pout,tmp);
  588.             }
  589.             else if (man && strcmp (w, ".EE") == 0) {
  590.                 if (EXEE == 0)
  591.                     fprintf(stderr,".EE with no matching .EX\n");
  592.                 else {
  593.                     --EXEE;
  594.                     pout = strapp(pout, "\\fill ");
  595.                 }
  596.             }
  597.             else if (man && strcmp (w, ".NT") == 0) {
  598.                 ++NTNE;
  599.                 pin += get_allargs (pin, &pw, 1);
  600.                 if (pw [0] == NULL)
  601.                     pout = strapp (pout, "\\beginnotec{NOTE}");
  602.                 else {
  603.                     if (strcmp (pw [0], "C") == 0) {
  604.                         if (pw [1])
  605.                             pout = strapp (pout, "\\beginnotec{NOTE}");
  606.                         else {
  607.                             sprintf (tmp, "\\beginnotec{%s}", pw [1]);
  608.                             pout = strapp (pout, tmp);
  609.                         }
  610.                     }
  611.                     else {
  612.                         sprintf (tmp, "\\beginnote{%s}", pw [0]);
  613.                         pout = strapp (pout, tmp);
  614.                     }
  615.                 }
  616.             }
  617.             else if (man && strcmp (w, ".NE") == 0) {
  618.                 if (NTNE == 0)
  619.                     fprintf(stderr,".NE with no matching .NT\n");
  620.                 else {
  621.                     --NTNE;
  622.                     pout = strapp(pout, "\n\\end{quote}\n");
  623.                 }
  624.             }
  625.             else if (strcmp(w,".TS") == 0)
  626.             {
  627.                 fprintf(stderr,"I am not very good at tables\n\
  628. I can only do very simple ones. You may need to check what I've done\n");
  629.                 pin = skip_line(pin);
  630.                 pout = do_table(pin,pout,&offset);
  631.                 pin += offset;
  632.                 offset = 0;        /* reset */
  633.             }
  634.             /* Now search for commands that start with small letters */
  635.             else if (strcmp(w,".TE") == 0) {
  636.                 fprintf(stderr,"Oops! I goofed. I told you I am not very good at tables.\nI have encountered a table end but I am not in table mode\n");
  637.             }
  638.             else if (strcmp(w,".de") == 0) {
  639.                 de_arg = 1;
  640.                 if (mydef_count >= MAXDEF) {
  641.                     fprintf(stderr,
  642.                             "Too many .de's. MAXDEF=%d\n",MAXDEF);
  643.                     exit(-1);
  644.                 }
  645.                 pin += skip_white(pin);
  646.                 pin += get_defword(pin,w,&illegal);
  647.                 pin += skip_white(pin);
  648.                 pin += get_mydef(pin,ww);
  649.                 mydef[mydef_count].arg_no = de_arg;
  650.                 if (illegal) {
  651.                     mydef[mydef_count].illegal = 1;
  652.                     fprintf(stderr,
  653.                             "illegal TeX macro, %s, replacing it\n",w);
  654.                     p = (char *)malloc((unsigned)(strlen(ww)+2)*
  655.                                        sizeof(char));
  656.                     sprintf(p,"%s",ww);
  657.                     mydef[mydef_count].replace = p;
  658.                 }
  659.                 else {
  660.                     mydef[mydef_count].illegal = 0;
  661.                     sprintf(tmp,"\\def\\%s",w);
  662.                     pout = strapp(pout,tmp);
  663.                     for (j=1; j<de_arg; j++) {
  664.                         sprintf(tmp,"#%d",j);
  665.                         pout = strapp(pout,tmp);
  666.                     }
  667.                     sprintf(tmp,"{%s}\n",ww);
  668.                     pout = strapp(pout,tmp);
  669.                 }
  670.                 p = (char *)malloc((unsigned)(strlen(w)+2)*sizeof(char));
  671.                 sprintf(p,".%s",w);
  672.                 mydef[mydef_count++].def_macro = p;
  673.                 pin = skip_line(pin);
  674.                 de_arg = 0;
  675.             }
  676.             else if (strcmp(w,".ds") == 0) {
  677.                 pin += get_arg(pin,w,0);
  678.                 pin += skip_white(pin);
  679.                 pin += get_line(pin,ww,1);
  680.                 if (strcmp(w,"LH") == 0) {
  681.                     sprintf(tmp,"\\lefthead{%s}",ww);
  682.                     pout = strapp(pout,tmp);
  683.                 }
  684.                 else if (strcmp(w,"RH") == 0) {
  685.                     sprintf(tmp,"\\righthead{%s}",ww);
  686.                     pout = strapp(pout,tmp);
  687.                 }
  688.                 else if (strcmp(w,"CF") == 0) {
  689.                     if (index(ww,'%') == 0) {
  690.                         sprintf(tmp,"\\footer{%s}",ww);
  691.                         pout = strapp(pout,tmp);
  692.                     }
  693.                     else
  694.                         pout = strapp(pout, "\\footer{\\rm\\thepage}");
  695.                 }
  696.                 else {
  697.                     fprintf(stderr,"I do not understand .ds %s\n",w);
  698.                     sprintf(tmp,"%%.ds %s %s",w,ww);
  699.                     pout = strapp(pout,tmp);
  700.                 }
  701.             }
  702.             else if (strcmp(w,".sp") == 0) {
  703.                 pin += get_arg(pin,ww,0);
  704.                 (void) get_size(ww,&space);
  705.                 sprintf(tmp,"\\par\\vspace{%3.1f%s}",space.value,space.units);
  706.                 pout = strapp(pout,tmp);
  707.             }
  708.             else if (strcmp(w,".in") == 0) {
  709.                 pin += get_arg(pin,ww,0);
  710.                 (void) get_size(ww,&indent);
  711.                 sprintf(tmp,"\\ind{%3.1f%s}",indent.value,indent.units);
  712.                 pout = strapp(pout,tmp);
  713.             }
  714.             else if (strcmp(w,".ls") == 0) {
  715.                 pin += get_arg(pin,ww,0);
  716.                 (void) get_size(ww,&linespacing);
  717.                 sprintf(tmp,"\\baselineskip=%3.1f%s",linespacing.value,
  718.                         linespacing.units);
  719.                 pout = strapp(pout,tmp);
  720.             }
  721.             else if (strcmp(w,".so") == 0) {
  722.                 pin += get_arg(pin,ww,0);
  723.                 sprintf(tmp,"\\input %s",ww);
  724.                 pout = strapp(pout,tmp);
  725.             }
  726.             else if (strcmp(w,".ti") == 0) {
  727.                 pin += get_arg(pin,ww,0);
  728.                 tmpind.value = indent.value;
  729.                 strcpy(tmpind.units,indent.units);
  730.                 (void) get_size(ww,&tmpind);
  731.                 sprintf(tmp,"\\tmpind{%3.1f%s}",
  732.                         tmpind.value,tmpind.units);
  733.                 pout = strapp(pout,tmp);
  734.             }
  735.             else if (strcmp(w,".vs") == 0) {
  736.                 pin += get_arg(pin,ww,0);
  737.                 (void) get_size(ww,&vspace);
  738.                 sprintf(tmp,"\\par\\vspace{%3.1f%s}",
  739.                         vspace.value,vspace.units);
  740.                 pout = strapp(pout,tmp);
  741.             }
  742.             /* check if it is a member of a group */
  743.             else if (mydef_count > 0 && (i=is_mydef(w)) >= 0) {
  744.                 if (mydef[i].par > 0) {
  745.                     if (de_arg > 0)
  746.                         mydef[mydef_count].par = mydef[i].par;
  747.                     else {
  748.                         pout = end_env(pout);
  749.                         pout = strapp(pout,"\n");
  750.                     }
  751.                 }
  752.                 if (mydef[i].illegal)
  753.                     pout = strapp(pout,mydef[i].replace);
  754.                 else {
  755.                     w[0] = '\\';    /* replace dot by backslash */
  756.                     pout = strapp(pout,w);
  757.                 }
  758.                 for (j=1; j <mydef[i].arg_no; j++) {
  759.                     pin += get_arg(pin,ww,1);
  760.                     sprintf(tmp,"{%s}",ww);
  761.                     pout = strapp(pout,tmp);
  762.                 }
  763.                 if (de_arg == 0)
  764.                     envoke_stat(mydef[i].par);
  765.             }
  766.             else if ((i=is_troff_mac(w,ww,&arg,&par)) >= 0) {
  767.                 if (par > 0) {
  768.                     if (de_arg > 0)
  769.                         mydef[mydef_count].par = par;
  770.                     else
  771.                         pout = end_env(pout);
  772.                 }
  773.                 pout = strapp(pout,ww);
  774.                 if (ww[0] == EOS)
  775.                     pin = skip_line(pin);
  776.                 if (ww[0] != EOS && arg == 0) {
  777.                     pin = skip_line(pin);
  778.                     *pout++ = '\n';
  779.                 }
  780.                 if (arg > 0) {
  781.                     if (arg == 1) {
  782.                         pin += skip_white(pin);
  783.                         pin += get_string(pin,ww,1);
  784.                     }
  785.                     else {
  786.                         if (isupper(w[1])) {
  787.                             pin = skip_line(pin);
  788.                             pin += get_multi_line(pin,ww);
  789.                         }
  790.                         else {
  791.                             pin += get_arg(pin,tmp,0);
  792.                             pin = skip_line(pin);
  793.                             if (tmp[0] == EOS)
  794.                                 N = 1;
  795.                             else
  796.                                 N = atoi(tmp);
  797.                             pin += get_N_lines(pin,ww,N);
  798.                         }
  799.                     }
  800.                     sprintf(tmp2,"{%s}",ww);
  801.                     pout = strapp(pout,tmp2);
  802.                 }
  803.             }
  804.             /* if none of the above commands matched, it is either
  805.                an illegal macro or an unknown command */
  806.             else {
  807.                 len = get_till_space(pin,ww);
  808.                 sprintf(tmp,"%s%s",w,ww);
  809.                 if (mydef_count > 0 && (i=is_mydef(tmp)) >= 0) {
  810.                     pin += len;
  811.                     if (mydef[i].par > 0) {
  812.                         if (de_arg > 0)
  813.                             mydef[mydef_count].par=mydef[i].par;
  814.                         else {
  815.                             pout = end_env(pout);
  816.                             pout = strapp(pout,"\n");
  817.                         }
  818.                     }
  819.                     pout = strapp(pout,mydef[i].replace);
  820.                     for (j=1; j <mydef[i].arg_no; j++) {
  821.                         pin += get_arg(pin,ww,1);
  822.                         sprintf(tmp,"{%s}",ww);
  823.                         pout = strapp(pout,tmp);
  824.                     }
  825.                     if (de_arg == 0)
  826.                         envoke_stat(mydef[i].par);
  827.                 }
  828.                 else {
  829.                     fprintf(stderr, "I cannot translate troff macro %s\n",w);
  830.                     pin += get_line(pin,ww,0);
  831.                     pout = strapp(pout,"%");
  832.                     pout = strapp(pout,w);
  833.                     pout = strapp(pout,ww);
  834.                     if (*pin == EOS)
  835.                         *pout++ = '\n';
  836.                 }
  837.             }
  838.         }
  839.         
  840.         /* some manuals have commented lines beginning with ''' */
  841.         else if (c2=='\'' && !mid && (c1=='\n' || c1==EOS || first_word)) {
  842.             if (*pin == '\'') {
  843.                 pin++;
  844.                 if (*pin == '\'') {
  845.                     pin++;
  846.                     pout = strapp(pout,"%");
  847.                 }
  848.                 else
  849.                     pout = strapp(pout,"''");
  850.             }
  851.             else
  852.                 pout = strapp(pout,"'");
  853.         }
  854.         
  855.         /* See if it is one of these symbols */
  856.         
  857.         else if (strcmp(w,"#") == 0 || strcmp(w,"&") == 0 ||
  858.                  strcmp(w,"{") == 0 || strcmp(w,"}") == 0 ||
  859.                  strcmp(w,"%") == 0 || strcmp(w,"_") == 0 ||
  860.                  strcmp(w,"~") == 0 || strcmp(w,"^") == 0 ) {
  861.             pout = strapp(pout,"\\");
  862.             pout = strapp(pout,w);
  863.             if (strcmp(w,"~") == 0 || strcmp(w,"^") == 0)
  864.                 pout = strapp(pout,"{}");
  865.         }
  866.         
  867.         else if (strcmp(w,">") == 0 || strcmp(w,"<") == 0
  868.                  || strcmp(w,"|") == 0) {
  869.             sprintf(tmp,"$%s$",w);
  870.             pout = strapp(pout,tmp);
  871.         }
  872.         
  873.         /* check for backslash commands */
  874.         
  875.         else if (strcmp(w,"\\") == 0) {
  876.             switch (*pin) {
  877.             case ' ':
  878.             case '\t':
  879.             case '\n':
  880.                 pout = strapp(pout,"\\");
  881.                 *pout++ = *pin++;
  882.                 break;
  883.             case EOS:
  884.                 break;
  885.             case '-':
  886.                 pin++;
  887.                 pout = strapp(pout,"--");
  888.                 break;
  889.             case '~':
  890.             case '^':
  891.                 pin++;
  892.                 pout = strapp(pout,"\\/");
  893.                 break;
  894.             case '0':
  895.                 pin++;
  896.                 pout = strapp(pout,"\\ ");
  897.                 break;
  898.             case 'e':
  899.                 pin++;
  900.                 pout = strapp(pout,"\\bs ");
  901.                 break;
  902.             case '\\':
  903.                 pin++;
  904.                 if (*pin == '$' && de_arg > 0) {
  905.                     pin++;
  906.                     de_arg++;
  907.                     *pout++ = '#';
  908.                 }
  909.                 else
  910.                     pout = strapp(pout,"\\bs ");
  911.                 break;
  912.             case '`':
  913.             case '\'':
  914.                 break;                /* do nothing */
  915.             case '"':
  916.                 pin++;
  917.                 pin += get_line(pin,ww,0);
  918.                 pout = strapp(pout,"%");
  919.                 pout = strapp(pout,ww);
  920.                 break;
  921.             case '|':
  922.                 pin++;
  923.                 pout = strapp(pout,"\\,");
  924.                 break;
  925.             case '&':
  926.                 pin++;
  927.                 break;
  928.             case '(':
  929.                 c1 = *++pin;
  930.                 c2 = *++pin;
  931.                 pin++;
  932.                 if (c1 == 'e' && c2 == 'm')
  933.                     pout = strapp(pout,"---");
  934.                 else if (c1 == 'd' && c2 == 'e')
  935.                     pout = strapp(pout,"$^\\circ$");
  936.                 else
  937.                     fprintf(stderr,
  938.                              "I am not prepared to handle \\(%c%c\n",c1,c2);
  939.                 break;
  940.             case 's':
  941.                 pin +=3;
  942.                 break;
  943.             case '*':
  944.                 c1 = *++pin;
  945.                 pin++;
  946.                 switch (c1) {
  947.                 case ':':    pout = strapp(pout,"\\\""); break;
  948.                 case 'C':    pout = strapp(pout,"\\v"); break;
  949.                 case ',':    pout = strapp(pout,"\\c"); break;
  950.                 case '(':
  951.                     sprintf(tmp,"\\%c",c1);
  952.                     pout = strapp(pout,tmp);
  953.                     break;
  954.                 default:
  955.                     fprintf(stderr,"I am not prepared to handle \\*( cases\n");
  956.                     pin += 2;
  957.                     break;
  958.                 }
  959.                 if (c1 != '(') {
  960.                     c1 = *pin++;
  961.                     sprintf(tmp,"{%c}",c1);
  962.                     pout = strapp(pout,tmp);
  963.                 }
  964.                 break;
  965.             case 'f':
  966.                 c1 = *++pin;
  967.                 pin++;
  968.                 switch (c1) {
  969.                 case '1':
  970.                 case 'R':
  971.                     lastfont = thisfont;
  972.                     thisfont = 1;
  973.                     if (isspace (*pin)) {
  974.                         *pout++ = ' ';
  975.                         pin++;
  976.                     }
  977.                     pout = strapp(pout,"%\n\\rm ");
  978.                     break;
  979.                 case '2':
  980.                 case 'I':
  981.                     lastfont = thisfont;
  982.                     thisfont = 2;
  983.                     if (isspace (*pin)) {
  984.                         *pout++ = ' ';
  985.                         pin++;
  986.                     }
  987.                     pout = strapp(pout,"%\n\\it ");
  988.                     break;
  989.                 case '3':
  990.                 case 'B':
  991.                     lastfont = thisfont;
  992.                     thisfont = 3;
  993.                     if (*pin == ' ' || *pin == '\t' ||
  994.                         *pin == '\n' || *pin == '\f') {
  995.                         *pout++ = ' ';    pin++;
  996.                     }
  997.                     pout = strapp(pout,"%\n\\bf ");
  998.                     break;
  999.                 case 'P':
  1000.                     /* preserve white space - from Nelson Beebe  */
  1001.                     if (isspace (*pin)) {
  1002.                         *pout++ = ' ';
  1003.                         pin++;
  1004.                     }
  1005.                     switch(lastfont) {
  1006.                     case 1:
  1007.                         pout = strapp(pout,"\\rm%\n");
  1008.                         thisfont = 1;
  1009.                         break;
  1010.                     case 2:
  1011.                         pout = strapp(pout,"\\it%\n");
  1012.                         thisfont = 2;
  1013.                         break;
  1014.                     case 3:
  1015.                         pout = strapp(pout,"\\bf%\n");
  1016.                         thisfont = 3;
  1017.                         break;
  1018.                     default:
  1019.                         pout = strapp(pout,"\\rm%\n");
  1020.                         thisfont = 1;
  1021.                         break;
  1022.                     }
  1023.                     break;
  1024.                 default:
  1025.                     fprintf(stderr, "I do not understand \\f%c yet\n",c1);
  1026.                     break;
  1027.                 }
  1028.                 break;
  1029.             default:
  1030.                 fprintf(stderr,"I am not prepared to handle \\%c\n",*pin++);
  1031.                 break;
  1032.             }
  1033.         }
  1034.         
  1035.         /* if non of the above checks, its a dull word; copy it */
  1036.         
  1037.         else
  1038.             pout = strapp(pout,w);
  1039.         *pout = EOS;
  1040.         ww[0] = EOS;
  1041.         tmp[0] = EOS;
  1042.         tmp2[0] = EOS;
  1043.         if (!no_word)
  1044.             first_word = 0;
  1045.     }
  1046.     /* if file end, close opened environments and delimitters */
  1047.     if (rec == 0) {
  1048.         if (IP_stat)    pout = strapp(pout,"\\end{IPlist}\n");
  1049.         if (QP_stat)    pout = strapp(pout,"\\end{quotation}\n");
  1050.         if (TP_stat)    pout = strapp(pout,"\\end{TPlist}\n");
  1051.     }
  1052.     
  1053.     *pout = EOS;
  1054. }
  1055.